
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Reflection;
using Excel;
using M0;
using Newtonsoft.Json;

public partial class ExcelHelp
    {
        private string spath;//excel 路径
        private DataTable mSheet = null;
    
        public ExcelHelp(string path)
        {
            字段值转换处理 = new Dictionary<string, MethodInfo>();
            

            var allClass = this.GetType().Assembly.GetTypes();
            foreach (var v in allClass)
            {
                var allM = v.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static);
                
                foreach (var VARIABLE in allM)
                {
                    var attri = VARIABLE.GetCustomAttribute<ExcelAttribute>();
                    if (attri != null)
                    {
                        字段值转换处理.Add(attri.sType, VARIABLE);
                    }
                }
            }
            
        
        
            // InitSuccess = false;
            FileStream mStream = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
            IExcelDataReader mExcelReader = ExcelReaderFactory.CreateOpenXmlReader(mStream);
            var mResultSet = mExcelReader.AsDataSet();
            if (mResultSet.Tables.Count > 0)
            {
                //默认读取第一个数据表
                mSheet = mResultSet.Tables[0];
            }

            // if (type == OpType.ReadAndWrite)
            // {
            //     StartWrite(excelFile);
            // }

            // InitSuccess = true;
        }

        private Dictionary<string, MethodInfo> 字段值转换处理;


        /// <summary>
        /// 获取一行数据
        /// </summary>
        /// <param name="index"></param>
        /// <returns></returns>
        public List<object> GetRowDatas(int index)
        {
            List<object> list = new List<object>();

            //判断Excel文件中是否存在数据表
            if (mSheet == null)
            {
                return list;
            }

            //默认读取第一个数据表

            //判断数据表内是否存在数据
            if (mSheet.Rows.Count <= index)
            {
                return list;
            }

            //读取数据
            int colCount = mSheet.Columns.Count;
            for (int j = 0; j < colCount; j++)
            {
                object item = mSheet.Rows[index][j];
                list.Add(item);
            }


            return list;
        }

        public Excel内容详情 get内容详情()
        {
            if (mSheet == null)
            {
                return Excel内容详情.Empty();
            }
        
            //准备一个列表存储整个表的数据
            List<Dictionary<string, object>> table = new List<Dictionary<string, object>>();

            var 字段名字和类型 = Get字段名字和类型();
            List<object> fieldNameRowDatas = 字段名字和类型.Item1;
            List<object> fieldTypeRowDatas = 字段名字和类型.Item2;
            int beginRow = 字段名字和类型.Item3;
            int beginColum = 字段名字和类型.Item4;
    
            bool isSuccess = true;
            //读取数据
            for (int i = beginRow + 1; i < mSheet.Rows.Count; i++)
            {
                //准备一个字典存储每一行的数据
                Dictionary<string, object> row = new Dictionary<string, object>();
                for (int j = beginColum; j < mSheet.Columns.Count; j++)
                {
                    string field = fieldNameRowDatas[j].ToString();
                    //跳过空字段
                    if (string.IsNullOrEmpty(field))
                    {
                        continue;
                    }

                    if (row.ContainsKey(field))
                    {
                        BDebug.Error($"重复字段！！！{field}");
                        continue;
                    }
                
                    //Key-Value对应
                    var rowdata = mSheet.Rows[i][j];
                    //根据null判断
                    if (rowdata == null)
                    {
                        BDebug.Error($"表格数据为空：[{i},{j}]");
                        continue;
                    }
                
                    var fieldType = fieldTypeRowDatas[j].ToString().ToLower();
                    if (字段值转换处理.ContainsKey(fieldType))
                    {
                        var obj = 字段值转换处理[fieldType]?.Invoke(null, new object[] {rowdata});
                        row.Add(field,obj);
                    }
                    else
                    {
                        BDebug.Error($"新的字段类型，请添加{fieldType}");
                        continue;
                    }
                }
            
                //添加到表数据中
                if (row.Count > 0)
                {
                    table.Add(row);
                }
            }

            string json = JsonConvert.SerializeObject(table);
            Excel内容详情 res = new Excel内容详情();
            res.b是否成功 = true;
            res.n最大columeCount = mSheet.Columns.Count;
            res.n有效columeCount = beginColum;
            res.n最大rowCount = mSheet.Rows.Count;
            res.n有效rowCount = beginRow;
            res.sJson = json;

            return res;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns>
        /// 字段名字
        /// 字段类型
        /// 开始的row index
        /// 开始的Colum index
        /// </returns>
        private (List<object>, List<object>,int idx,int idy) Get字段名字和类型()
        {
            List<object> fieldNameRowDatas = new List<object>();
            List<object> fieldTypeRowDatas = new List<object>();
        
            //第一行为备注，
            //寻找到id字段行数，以下全为数据
            int skipRowCount = -1;
            int skipColCount = -1;

            //这里skip 防止有人在 备注行直接输入id
            int skipLine = 1;
            for (int i = skipLine; i < 10 && skipColCount == -1; i++)
            {
                var rows = this.GetRowDatas(i);
                //遍历rows
                for (int j = 0; j < rows.Count; j++)
                {
                    if (rows[j].Equals("Id") || rows[j].Equals("id"))
                    {
                        skipRowCount = i;
                        skipColCount = j;
                        fieldNameRowDatas = rows;
                        //获取字段类型
                        var rowtype = this.GetRowDatas(i - 1);
                        fieldTypeRowDatas = rowtype;
                        //
                        break;
                    }
                }
            }

            return (fieldNameRowDatas, fieldTypeRowDatas,skipRowCount,skipColCount);
        }
    }

    public class Excel内容详情
    {
        public bool b是否成功;
        public string sJson;
        public int n有效rowCount;
        public int n最大rowCount;
        public int n有效columeCount;
        public int n最大columeCount;

        public static Excel内容详情 Empty()
        {
            return new Excel内容详情() {b是否成功 = false};
        }
    }